from pinecone import Pinecone, ServerlessSpec

pc = Pinecone(api_key="pcsk_4js8wK_9HDCxEApcaiaSiAibHfiHkgeP98qpaV27QoyeqJn2tv2biGZKhN8pX9MXuxpE2H")
index_name = "mnist-index"
index = pc.Index(index_name)
################### 检查、清除之前创建的索引 ###################
# 通过客户端实例获取现有索引列表
existing_indexes = pc.list_indexes()
index_names = existing_indexes.names()  # 获取所有索引名称的列表

# 检查索引是否存在，如果存在就删除
if index_name in index_names:
    print(f"索引 '{index_name}' 已存在，正在删除...")
    pc.delete_index(index_name)
    print(f"索引 '{index_name}' 已成功删除。")
else:
    print(f"索引 '{index_name}' 不存在，将创建新索引。")
################### 检查、清除之前创建的索引 ###################

# 创建新索引（通过客户端实例操作）
print(f"正在创建新索引 '{index_name}'...")
pc.create_index(
    name=index_name,
    dimension=64,  # 根据你的数据维度调整
    metric="euclidean",
    spec=ServerlessSpec(
        cloud="aws",
        region="us-east-1"
    )
)
print(f"索引 '{index_name}' 创建成功。")


# 连接到索引（通过客户端实例获取）
index = pc.Index(index_name)
print(f"已成功连接到索引 '{index_name}'。")

[{
    "name": "mnist-index",
    "dimension": 64,
    "metric": "euclidean",
    "host": "mnist-index-il86agr.svc.aped-4627-b74a.pinecone.io",
    "spec": {
        "serverless": {
            "cloud": "aws",
            "region": "us-east-1"
        }
    },
    "status": {
        "ready": True,
        "state": "Ready"
    },
    "deletion_protection": "disabled"
}]



    
# 从 scikit-learn 库中导入 load_digits 函数
# 这个函数用于加载著名的手写数字数据集 MNIST
from sklearn.datasets import load_digits

# 使用 load_digits 函数加载 MNIST 数据集
# n_class=10 表示加载全部 10 个数字类别(0-9)
digits = load_digits(n_class=10)

# 获取数据集中的特征数据
# X 是一个二维数组,每行代表一个样本,每个样本是一个 64 维的向量(8x8 像素展平)
X = digits.data

# 获取数据集中的标签
# y 是一个一维数组,包含每个样本对应的真实数字标签(0-9)
y = digits.target

# 初始化一个空列表,用于存储转换后的向量数据
vectors = []

# 遍历所有样本,将数据转换为 Pinecone 可接受的格式
for i in range(len(X)):
    # 使用样本的索引作为向量的唯一标识符
    vector_id = str(i)
    
    # 将 NumPy 数组转换为 Python 列表
    # Pinecone 要求输入数据为 Python 列表格式
    vector_values = X[i].tolist()
    
    # 创建元数据字典,包含该样本的真实标签
    # 将标签转换为整数类型,确保数据类型的一致性
    metadata = {"label": int(y[i])}
    
    # 将转换后的数据(ID、向量值、元数据)作为元组添加到 vectors 列表中
    vectors.append((vector_id, vector_values, metadata))

# 定义批处理大小,每批最多包含 1000 个向量
# 这是为了避免一次性向 Pinecone 发送过多数据,可能导致请求超时或失败
batch_size = 1000

# 使用步长为 batch_size 的 range 函数,实现分批处理
for i in range(0, len(vectors), batch_size):
    # 从 vectors 列表中切片获取一批数据
    batch = vectors[i:i + batch_size]
    
    # 使用 upsert 方法将这批数据上传到 Pinecone 索引中
    # upsert 操作会插入新的向量或更新已存在的向量
    index.upsert(batch)

    print(f"已成功上传 {len(batch)} 个向量到索引 '{index_name}'。")